﻿' ----------------------------------------------------------------------------------
' Microsoft Developer & Platform Evangelism
' 
' Copyright (c) Microsoft Corporation. All rights reserved.
' 
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
' OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ----------------------------------------------------------------------------------
' The example companies, organizations, products, domain names,
' e-mail addresses, logos, people, places, and events depicted
' herein are fictitious.  No association with any real company,
' organization, product, domain name, email address, logo, person,
' places, or events is intended or should be inferred.
' ----------------------------------------------------------------------------------

Imports System.Globalization
Imports System.Net.Browser
Imports System.Runtime.Serialization
Imports Microsoft.Samples.WindowsPhoneCloud.StorageClient.Credentials
Imports Microsoft.Samples.WindowsPhoneCloud.StorageClient.Serializers

Public Class SharedAccessSignatureServiceClient
    Implements ISharedAccessSignatureServiceClient

    Private Const GetContainerSharedAccessSignatureOperation As String = "container"
    Private Const GetBlobSharedAccessSignatureOperation As String = "blob"

    Private sasServiceAddress As Uri

    Private clientHttpValue As IWebRequestCreate

    Public Sub New(ByVal sasServiceAddress As String, ByVal credentials As IStorageCredentials)
        Me.sasServiceAddress = New Uri(sasServiceAddress, UriKind.Absolute)
        Me.StorageCredentials = credentials
    End Sub

    Public Property StorageCredentials() As IStorageCredentials

    Friend Property ClientHttp() As IWebRequestCreate
        Get
            Return If(Me.clientHttpValue IsNot Nothing, Me.clientHttpValue, WebRequestCreator.ClientHttp)
        End Get

        Set(ByVal value As IWebRequestCreate)
            Me.clientHttpValue = value
        End Set
    End Property


    Public Sub GetContainerSharedAccessSignature(ByVal callback As Action(Of CloudOperationResponse(Of Uri))) Implements ISharedAccessSignatureServiceClient.GetContainerSharedAccessSignature
        ' Adding an incremental seed to avoid a cached response.
        Dim request = Me.CreateGetOperationRequest(String.Format(CultureInfo.InvariantCulture, "{0}?&incrementalSeed={1}", GetContainerSharedAccessSignatureOperation, Date.UtcNow.Ticks))

        request.BeginGetResponse(
            Sub(ar)
                Try
                    Dim response = request.EndGetResponse(ar)
                    Dim serializer = New DataContractSerializer(GetType(Uri))
                    Dim containerUri = TryCast(serializer.ReadObject(response.GetResponseStream()), Uri)
                    callback(New CloudOperationResponse(Of Uri)(containerUri, Nothing))
                Catch exception As Exception
                    Dim parsedException = StorageClientExceptionParser.ParseStringWebException(TryCast(exception, WebException))
                    If parsedException IsNot Nothing Then
                        callback(New CloudOperationResponse(Of Uri)(Nothing, parsedException))
                    Else
                        callback(New CloudOperationResponse(Of Uri)(Nothing, exception))
                    End If
                End Try
            End Sub,
            Nothing)
    End Sub

    Public Sub GetBlobsSharedAccessSignatures(ByVal blobPrefix As String, ByVal useFlatBlobListing As Boolean, ByVal callback As Action(Of CloudOperationResponse(Of IEnumerable(Of ICloudBlob)))) Implements ISharedAccessSignatureServiceClient.GetBlobsSharedAccessSignatures
        ' Adding an incremental seed to avoid a cached response.
        Dim serviceOperation = If((Not String.IsNullOrEmpty(blobPrefix)), String.Format(CultureInfo.InvariantCulture, "{0}?blobPrefix={1}&useFlatBlobListing={2}&incrementalSeed={3}", GetBlobSharedAccessSignatureOperation, blobPrefix.Replace("\", "/"), useFlatBlobListing, Date.UtcNow.Ticks), String.Format(CultureInfo.InvariantCulture, "{0}?useFlatBlobListing={1}&incrementalSeed={2}", GetBlobSharedAccessSignatureOperation, useFlatBlobListing, Date.UtcNow.Ticks))
        Dim request = Me.CreateGetOperationRequest(serviceOperation)

        request.BeginGetResponse(
            Sub(ar)
                Try
                    Dim response = request.EndGetResponse(ar)
                    Dim serializer = New SharedAccessSignatureDataContractSerializer()
                    Dim results = serializer.ReadObject(response.GetResponseStream())
                    callback(New CloudOperationResponse(Of IEnumerable(Of ICloudBlob))(results, Nothing))
                Catch exception As Exception
                    Dim parsedException = StorageClientExceptionParser.ParseStringWebException(TryCast(exception, WebException))
                    If parsedException IsNot Nothing Then
                        callback(New CloudOperationResponse(Of IEnumerable(Of ICloudBlob))(Nothing, parsedException))
                    Else
                        callback(New CloudOperationResponse(Of IEnumerable(Of ICloudBlob))(Nothing, exception))
                    End If
                End Try
            End Sub, Nothing)
    End Sub

    Private Function CreateGetOperationRequest(ByVal serviceOperation As String) As WebRequest
        Dim operationUri = New Uri(String.Format(CultureInfo.InvariantCulture, "{0}/{1}", Me.sasServiceAddress, serviceOperation))
        Dim request = Me.ClientHttp.Create(operationUri)
        request.Method = "GET"

        Me.StorageCredentials.SignRequestLite(request)

        Return request
    End Function

End Class